package com.xlh.service.courseTest.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.xlh.dto.QuestionTransportDTO;
import com.xlh.enums.courseTest.QuestionTypeEnum;
import com.xlh.pojo.courseTest.CourseQuestionRepository;
import com.xlh.pojo.courseTest.CourseQuestionRepositoryDetails;
import com.xlh.service.courseTest.QuestionRepositoryDetailsService;
import com.xlh.service.courseTest.QuestionRepositoryService;
import com.xlh.service.courseTest.QuestionTransportService;
import com.xlh.util.JDBCTemplateUtil;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class QuestionTransportServiceImpl implements QuestionTransportService {

    @Autowired
    private QuestionRepositoryService questionRepositoryService;
    @Autowired
    private QuestionRepositoryDetailsService questionRepositoryDetailsService;

    @Override
    public QuestionTransportDTO transportAll(JdbcTemplate jdbcTemplate, Long userId, Map<Long, Long> courseIdMap, Map<Long, Long> chapterIdMap) {
        String sql = "select " +
                "id, course_id, chapter_id, is_preset, business_type, question_type, md_content, html_content, jx_content, jx_content_html " +
                "from course_question_repository " +
                "where del_mark = 0 and course_id = ?";

        // 取出远程数据库的课程id
        Long courseId = courseIdMap.keySet().iterator().next();

        RowMapper<CourseQuestionRepository> rowMapper = new BeanPropertyRowMapper<>(CourseQuestionRepository.class);
        List<CourseQuestionRepository> questionList = jdbcTemplate.query(sql, rowMapper, courseId);

        return transport(jdbcTemplate, userId, questionList, courseIdMap, chapterIdMap);
    }

    /**
     * 将从外部数据源获取的数据导入本地数据库
     *
     * @param questionList 题目列表
     * @param answerList   答案选项列表
     * @return 本地新增的新questionId集
     */
    private QuestionTransportDTO transport(List<CourseQuestionRepository> questionList, List<CourseQuestionRepositoryDetails> answerList, Long userId) {

        // 获取实验题questionId
        List<Long> experimentIds = questionList.stream().filter(question -> QuestionTypeEnum.EXPERIMENT.getCode().equals(question.getQuestionType())).map(CourseQuestionRepository::getId).collect(Collectors.toList());

        // 提取question中的id
        List<Long> questionIds = questionList.stream().map(CourseQuestionRepository::getId).collect(Collectors.toList());

        // 清除question中的id
        // 设置userId
        for (CourseQuestionRepository courseQuestionRepository : questionList) {
            courseQuestionRepository.setId(null);
            courseQuestionRepository.setUserId(userId);
        }

        // 批量insert question
        questionRepositoryService.insertBatch(questionList);

        // 提取question中的newId
        List<Long> newQuestionIds = questionList.stream().map(CourseQuestionRepository::getId).collect(Collectors.toList());

        // 对id和newId生成映射
        Map<Long, Long> questionIdMap = toMap(questionIds, newQuestionIds);

        // 修改answer中的questionId
        for (CourseQuestionRepositoryDetails details : answerList) {
            details.setQuestionId(questionIdMap.get(details.getQuestionId()));
        }

        // 批量insert answer
        questionRepositoryDetailsService.insertBatch(answerList);
        // 返回newIds
        Map<Long, Long> exprimentIdMap = new HashMap<>();
        if(CollectionUtil.isNotEmpty(experimentIds)){
            questionIdMap.forEach((k,v) -> {
                if(experimentIds.contains(k)){
                    exprimentIdMap.put(k,v);
                }
            });
        }
        QuestionTransportDTO questionTransportDTO = new QuestionTransportDTO();
        questionTransportDTO.setExprimentIdsMap(exprimentIdMap);
        questionTransportDTO.setNewQuestionIds(newQuestionIds);

        return questionTransportDTO;
    }

    private Map<Long, Long> toMap(List<Long> questionIds, List<Long> newQuestionIds) {
        Map<Long, Long> result = Maps.newHashMap();

        int length = questionIds.size();
        for (int i = 0; i < length; i++) {
            result.put(questionIds.get(i), newQuestionIds.get(i));
        }

        return result;
    }

    /**
     * 查询answer对象
     *
     * @param jdbcTemplate 数据源连接
     * @param questionIds  以questionId做查询条件
     * @return answerList
     */
    private List<CourseQuestionRepositoryDetails> getAnswerList(JdbcTemplate jdbcTemplate, List<Long> questionIds) {
        if (CollectionUtils.isEmpty(questionIds)) {
            return Lists.newArrayList();
        }

        String sql = "select " +
                "question_id, order_number, is_correct, md_content, html_content " +
                "from course_question_repository_details " +
                "where del_mark = 0 and question_id in (:questionIds)";

        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("questionIds", questionIds);

        NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);

        RowMapper<CourseQuestionRepositoryDetails> rowMapper = new BeanPropertyRowMapper<>(CourseQuestionRepositoryDetails.class);

        return namedParameterJdbcTemplate.query(sql, paramMap, rowMapper);
    }

    @Override
    public QuestionTransportDTO transport(JdbcTemplate jdbcTemplate, Long userId, Map<Long, Long> courseIdMap, Map<Long, Long> chapterIdMap, boolean isAllTransport) {
        // 判断是否需要全部导入，并执行不同的方法
        if (isAllTransport) {
            return transportAll(jdbcTemplate, userId, courseIdMap, chapterIdMap);
        } else {
            return transportChapterNotNull(jdbcTemplate, userId, courseIdMap, chapterIdMap);
        }
    }

    @Override
    public QuestionTransportDTO transportChapterNull(JdbcTemplate jdbcTemplate, Long userId, Map<Long, Long> courseIdMap) {
        String sql = "select " +
                "id, course_id, chapter_id, is_preset, business_type, question_type, md_content, html_content " +
                "from course_question_repository " +
                "where del_mark = 0 and course_id = ?";

        // 取出远程数据库的课程id
        Long courseId = courseIdMap.keySet().iterator().next();

        RowMapper<CourseQuestionRepository> rowMapper = new BeanPropertyRowMapper<>(CourseQuestionRepository.class);
        List<CourseQuestionRepository> questionList = jdbcTemplate.query(sql, rowMapper, courseId);

        return transport(jdbcTemplate, userId, questionList, courseIdMap, null);
    }

    @Override
    public QuestionTransportDTO transportChapterNotNull(JdbcTemplate jdbcTemplate, Long userId, Map<Long, Long> courseIdMap, Map<Long, Long> chapterIdMap) {
        String sql = "select " +
                "id, course_id, chapter_id, is_preset, business_type, question_type, md_content, html_content, jx_content, jx_content_html " +
                "from course_question_repository " +
                "where del_mark = 0 and course_id = :courseId and chapter_id in (:chapterIds)";

        // 取出远程数据库的课程id
        Long courseId = courseIdMap.keySet().iterator().next();

        // 取出远程数据库的章节id
        List<Long> chapterIds = Lists.newArrayList(chapterIdMap.keySet());

        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("courseId", courseId);
        paramMap.put("chapterIds", chapterIds);

        RowMapper<CourseQuestionRepository> rowMapper = new BeanPropertyRowMapper<>(CourseQuestionRepository.class);

        NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
        List<CourseQuestionRepository> questionList = namedParameterJdbcTemplate.query(sql, paramMap, rowMapper);

        return transport(jdbcTemplate, userId, questionList, courseIdMap, chapterIdMap);
    }

    /**
     * 重新设置questionList的courseId，chapterId，并查询answerList
     *
     * @param jdbcTemplate 外部数据源连接
     * @param userId       管理人用户id
     * @param questionList 外部数据源题目
     * @param courseIdMap  课程id映射
     * @param chapterIdMap 章节id映射
     * @return
     */
    private QuestionTransportDTO transport(JdbcTemplate jdbcTemplate, Long userId, List<CourseQuestionRepository> questionList, Map<Long, Long> courseIdMap, Map<Long, Long> chapterIdMap) {
        // 重新设置courseId和chapterId
        for (CourseQuestionRepository courseQuestionRepository : questionList) {
            courseQuestionRepository.setCourseId(courseIdMap.get(courseQuestionRepository.getCourseId()));
            if (courseQuestionRepository.getChapterId() != null) {
                courseQuestionRepository.setChapterId(chapterIdMap.get(courseQuestionRepository.getChapterId()));
            }
        }

        List<Long> questionIds = questionList.stream().map(CourseQuestionRepository::getId).collect(Collectors.toList());
        List<CourseQuestionRepositoryDetails> answerList = getAnswerList(jdbcTemplate, questionIds);

        return transport(questionList, answerList, userId);
    }


    public static void main(String[] args) {
        JdbcTemplate jdbcTemplate = JDBCTemplateUtil.getJdbcTemplate("localhost", "3306", "teaching_experiment_system", "root", "");

        List<Long> questionIds = Lists.newArrayList(1L, 2L, 3L, 4L);

        String sql = "select " +
                "question_id, order_number, is_correct, md_content, html_content " +
                "from course_question_repository_details " +
                "where del_mark = 0 and question_id in (:questionIds)";

        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("questionIds", questionIds);

        NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);

        RowMapper<CourseQuestionRepositoryDetails> rowMapper = new BeanPropertyRowMapper<>(CourseQuestionRepositoryDetails.class);

        List<CourseQuestionRepositoryDetails> list = namedParameterJdbcTemplate.query(sql, paramMap, rowMapper);

        System.out.println(list);
    }
}
